package com.inikolova.numericpuzzle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Point;


/**
 * Instances of this class represent SWT user interface for a numeric puzzle
 * @author nikol
 *
 */
public class NumericPuzzleViewer {

	public static final int BUTTON_SIZE = 80;
	
	/**
	 * Creates a window representing a numeric puzzle
	 * @param puzzle - a numeric puzzle instance that will be displayed and ordered
	 */
	public void CreateMainView(final NumericPuzzle puzzle) {
		final Display display = new Display();
		final Shell shell = new Shell(display);
		shell.setText("Numetic puzzle");
		
		final Button[] buttonList = new Button[puzzle.getCellsCount()];
		
		// Creation of buttons
		int buttonId = 0;
		
		for (int x = 0; x < puzzle.getWidth(); x++) {
			for (int y = 0; y < puzzle.getHeight(); y++) {
				int puzzleCellId = puzzle.getCellId(new Position(x,y));
				
				if (puzzleCellId == NumericPuzzle.FREE_CELL_ID) {
					// Create label representing the free cell
					final Label freeCell = new Label(shell, SWT.FLAT | SWT.CENTER);
					
					freeCell.setSize(BUTTON_SIZE, BUTTON_SIZE);
					//freeCell.setText("XXX");
					freeCell.setLocation(x * BUTTON_SIZE, y * BUTTON_SIZE);
					
					DropTarget dropTarget = new DropTarget(freeCell, DND.DROP_MOVE);
					dropTarget.setTransfer(new Transfer[] {TextTransfer.getInstance()});
					dropTarget.addDropListener(
							new DropTargetAdapter() {
								public void drop(DropTargetEvent event) {
									//System.out.println("drop " + event.data);
									
									int draggedCellId = Integer.parseInt((String)event.data);
									
									// Move the button to the free cell's location
									Point targetLocation = freeCell.getLocation();
									for (int i = 0; i < buttonList.length; i++) {
										if (Integer.parseInt(buttonList[i].getText()) == draggedCellId) {
											buttonList[i].setLocation(targetLocation);
											break;
										}
									}
									
									// Move the free cell to the button's location
									targetLocation = getLocationForButtonId(draggedCellId, puzzle);
									freeCell.setLocation(targetLocation);
									
									// Re-arrange the puzzle and check if it is ordered
									puzzle.swapWithFreeCell(draggedCellId);
									//System.out.println(puzzle);
									if (puzzle.isOrdered()) {
										MessageBox messageBox = new MessageBox(shell);
										messageBox.setMessage("Puzzle ordered");
										messageBox.open();
									}
								}
							}
					);
				} else {
					// Create a button representing ordinary movable cell
					final Button button = new Button(shell, SWT.FLAT);
					button.setText(String.valueOf(puzzleCellId));
					button.setSize(BUTTON_SIZE, BUTTON_SIZE);
					button.setLocation(x * BUTTON_SIZE, y * BUTTON_SIZE);
					
					buttonList[buttonId] = button;
					buttonId += 1;
					
					DragSource dragSource = new DragSource(button, DND.DROP_MOVE);
					dragSource.setTransfer(new Transfer[] {TextTransfer.getInstance()});
					dragSource.addDragListener(
						new DragSourceAdapter() {
							public void dragSetData(DragSourceEvent event) {
								//System.out.println("dragSetData " + button.getText());
								event.data = button.getText();
							}
							public void dragStart(DragSourceEvent event) {
								if (!puzzle.isSwapWithFreeCellAllowed(Integer.parseInt(button.getText()))) {
									event.doit = false;
								}
							}
						}
					);
				}
			} // end of inner for
		} // end of outer for

		// Vizualize the shell
		shell.pack();
		shell.open();
		while (!shell.isDisposed ()) {
			if (!display.readAndDispatch ()) display.sleep ();
		}
		display.dispose ();
	}
	
	/**
	 * Gets the SWT location of a button with a specified ID
	 * @param cellId - the ID of the cell in the puzzle
	 * @param puzzle - the numeric puzzle
	 * @return
	 */
	private Point getLocationForButtonId(int cellId, NumericPuzzle puzzle) {
		// [0,0] is upper left
		Position cellPosition = puzzle.getCellPostion(cellId);
		return new Point(cellPosition.getX() * BUTTON_SIZE, cellPosition.getY() * BUTTON_SIZE);
	}

}
